

/**
 * @file CSDetectorDeltaUC.hpp
 */

#ifndef GPSTK_CSDetectorDeltaUC_HPP
#define GPSTK_CSDetectorDeltaUC_HPP


#include <deque>
#include "ProcessingClass.hpp"
#include "CSDetectorDeltaLC.hpp"

namespace gpstk
{

      /** @addtogroup GPSsolutions */
      //@{

   class CSDetectorDeltaUC : public ProcessingClass
   {
   public:

         /// Default constructor, setting default parameters.
      CSDetectorDeltaUC() 
          : sampleInterval(30), deltaTMax(91.0), threshold(0.10),
            pLCDetector(NULL)
      {};


         /** Returns a satTypeValueMap object, adding the new data generated
          *  when calling this object.
          *
          * @param epoch     Time of observations.
          * @param gData     Data object holding the data.
          * @param epochflag Epoch flag.
          */
      virtual satTypeValueMap& Process( const CommonTime& epoch,
                                        satTypeValueMap& gData )
         noexcept(false);

      virtual void setLCDetector(CSDetectorDeltaLC& detector)
      {
          pLCDetector = &detector;
      };

      virtual double getDeltaTMax() const
      { return deltaTMax; };


      /* Method to set the maximum interval of time allowed between two
       * successive epochs.
       *
       * @param maxDelta      Maximum interval of time, in seconds
       */
      virtual CSDetectorDeltaUC& setDeltaTMax(const double& maxDelta)
      {
            // Don't allow delta times less than or equal to 0
         if (maxDelta > 0.0)
         {
            deltaTMax = maxDelta;
         }
         else
         {
            deltaTMax = 31.0;
         }

         return (*this);

      }  // End of method 'CSDetectorDeltaUC::setDeltaTMax()'

      virtual CSDetectorDeltaUC& setSampleInterval(const double& interval)
      {
          sampleInterval = interval;
          return (*this);
      }  // End of method 'CSDetectorDeltaUC::setDeltaTMax()'
         /// Method to know if the LLI check is enabled or disabled.
      virtual bool getUseLLI() const
      { return useLLI; };


         /** Method to set whether the LLI indexes will be used as an aid
          *  or not.
          *
          * @param use   Boolean value enabling/disabling LLI check
          */
      virtual CSDetectorDeltaUC& setUseLLI(const bool& use)
      { useLLI = use; return (*this); };


         /** Returns a gnnsRinex object, adding the new data generated when
          *  calling this object.
          *
          * @param gData    Data object holding the data.
          */
      virtual void Process(gnssRinex& gData)
         noexcept(false);


      virtual CSDetectorDeltaUC& addType(const TypeID& type, const SatID::SatelliteSystem& sys)
      {
          if(sys==SatelliteSystem::GPS)
          {
              usingGPS = true;
              gpsTypeSet.insert(type);
          }
          else if(sys==SatelliteSystem::Galileo)
          {
              usingGAL = true;
              galTypeSet.insert(type);
          }
          else if(sys==SatelliteSystem::BDS)
          {
              usingBDS = true;
              bdsTypeSet.insert(type);
          }
          return (*this);
      };


      virtual void setSatDataStream(std::ofstream& stream)
      {
          pUCDataStream = &stream;
      };


         /// Returns a string identifying this object.
      virtual std::string getClassName(void) const;


         /// Destructor
      virtual ~CSDetectorDeltaUC() {};


   private:

      bool usingGPS;
      bool usingGAL;
      bool usingBDS;

      TypeIDSet gpsTypeSet;
      TypeIDSet galTypeSet;
      TypeIDSet bdsTypeSet;

      /// Maximum interval of time allowed between two successive epochs,
      /// in seconds.
      double deltaTMax;

      double threshold;

         /// This field tells whether to use or ignore the LLI indexes as
         /// an aid.
      bool useLLI;

      epochDeltaXMap epochDeltaXData;

      CSDetectorDeltaLC* pLCDetector;

      struct formerData
      {
         formerData()
            : epoch(CommonTime::BEGINNING_OF_TIME),
              prefitL1(0.0),
              prefitL2(0.0),
              prefitL5(0.0),
              prefitL7(0.0),
              prefitL8(0.0),
              prefitL6(0.0),
              prefitWL12(0.0),
              prefitWL15(0.0),
              prefitWL27(0.0)
         {};

         CommonTime epoch;
         double prefitL1;
         double prefitL2;
         double prefitL5;
         double prefitL7;
         double prefitL8;
         double prefitL6;
         double prefitWL12(0.0);
         double prefitWL15(0.0);
         double prefitWL27(0.0);

      };

      std::map<SatID, formerData> oldPrefitData;

      satTypeValueMap satDataPrev;

      std::ofstream* pUCDataStream;


  }; // End of class 'CSDetectorDeltaUC'

      //@}

}  // End of namespace gpstk

#endif   // GPSTK_CSDetectorDeltaUC_HPP
